package particle;

import java.awt.Point;
import java.util.ArrayList;

import processing.core.PImage;
import processing.core.PVector;
import SimpleOpenNI.SimpleOpenNI;

public class ParticlePositionThread implements Runnable{
	SimpleOpenNI context;
	boolean isRunning;
	ArrayList<Particle> particles;
	PImage reset_btn;
	PImage water_btn;
	boolean reset_res;
	int reset_cnt = 0;
	boolean oncePushed_reset;
	long water_start;
	Point native_res;
	
	boolean reset_wat;
	int water_cnt = 0;
	
	ParticleSystem pSystem;
	
	public ParticlePositionThread(SimpleOpenNI context, ArrayList<Particle> particles, PImage reset_btn, ParticleSystem pSystem, PImage water_btn, Point native_res) {
		isRunning = true;
		this.context = context;
		this.particles = particles;
		this.reset_btn = reset_btn;		
		this.pSystem = pSystem;
		this.water_btn = water_btn;
		this.native_res = native_res;
	}
	
	@Override
	public void run() {
		while(isRunning){
			

			int userCount = context.getNumberOfUsers();
			int[] userMap = null;
			if (userCount > 0) {
				userMap = context.getUsersPixels(SimpleOpenNI.USERS_ALL);
			}

			int[][] usermap_2d = null;
			usermap_2d = new int[context.depthWidth()][context.depthHeight()];
			if (userCount > 0) {
				userMap = context.getUsersPixels(SimpleOpenNI.USERS_ALL);	
				
				int width = context.depthWidth();
				for (int i = 0; i < userMap.length; i++) {
					int x = i % width;
					int y = i / width;
					
					usermap_2d[x][y] = userMap[i];
				}

				
			}
			for (Particle elem : particles) {
				if(userMap!=null){
					int x_part = (int)(elem.loc.x/3);
					int y_part = (int)(elem.loc.y/3);
					int index = x_part+y_part*context.depthWidth();
					if( index > 0 && index <userMap.length-1 && userMap[(x_part+y_part*context.depthWidth())-1] != 0 ){

							if(elem.inUserArray == false){
								double angle = escapeAngle(usermap_2d, x_part, y_part, context.depthWidth());
								angle = angle/360*2*Math.PI;
								PVector tmp = new PVector( (float)Math.cos(angle), (float)Math.sin(angle));
								tmp.normalize();
								tmp.mult(5f);
								elem.vel.add( tmp);
								elem.inUserArray = true;
								elem.color = 0xFFFFFFFF;
							}else{
								elem.vel.normalize();
								elem.vel.mult(5f);
								elem.color = 0xFF000000;
							}

						}else{
							if(elem.inUserArray == true){
								elem.vel.normalize();
								elem.inUserArray = false;
								elem.color = 0xFFFFFFFF;
							}
							
						}
					
					
				}
			}
			
			//reset_button
			reset_res = false;
			for (int i = native_res.x-reset_btn.width-20; i < native_res.x-20 && !reset_res; i+=5) {
				for (int j = native_res.y-reset_btn.height-20; j < native_res.y-20  && !reset_res; j+=5) {
					
					if(usermap_2d[i/3][j/3] != 0){
						reset_res = true;
						reset_cnt++;
					}
					
				}
				
			}
			
			if(reset_res == false){
				if(oncePushed_reset){
					pSystem.force_disable_home();
				}
				reset_cnt = 0;
				oncePushed_reset = false;
			}
			
			if(reset_cnt >30 && oncePushed_reset == false){
				System.out.println("bam");
				pSystem.force_home();
				oncePushed_reset = true;
			}
			
			
			//water_button
			reset_wat = false;
			for (int i = 20; i < water_btn.width+20 && !reset_wat; i+=5) {
				for (int j = native_res.y-water_btn.height-20; j < native_res.y-water_btn.height  && !reset_wat; j+=5) {
					
					if(usermap_2d[i/3][j/3] != 0){
						reset_wat = true;
						water_cnt++;
					}
					
				}
				
			}
			
			if(reset_wat == false  ){
				water_cnt = 0;
			}
			
			if(water_cnt >30 || ( System.currentTimeMillis() <= (water_start+5000) ) ){
				pSystem.gravity();
				
				if(water_cnt >30){
					water_start = System.currentTimeMillis();
				}
			}
			
			
			try {
				Thread.sleep(10);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
		}
		
	}
	
	public double escapeAngle(int[][] array, int x, int y, int width_p){
		int maxRadius = 20;
		int width = array.length;
		int height = array[0].length;
		for (int i = 1; i < maxRadius; i++) {
			
			if(x+i < width && y+i < height && x-i >= 0 && y-i >= 0){
				int n = array[x][y-i];
				int w = array[x-i][y];
				int e = array[x+i][y];
				int s = array[x][y+i];
				int nw = array[x-i][y-i];
				int ne = array[x+i][y-i];
				int se = array[x+i][y+i];
				int sw = array[x-i][y+i];
				
				if(s == 0){
					return 90;
				}else if(w == 0){
					return 180;
				}else if(n == 0){
					return 270;
				}else if(e == 0){
					return 0;
				}else if(nw == 0){
					return 225;
				}else if(ne == 0){
					return 315;
				}else if(sw == 0){
					return 135;
				}else if(se == 0){
					return 45;
				}
			}


			
		}

		return Math.random()*360;
	}

}
